/**
 * FssLogger.java
 */
package fss.core.logger;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.FileHandler;
import java.util.logging.Logger;

import fss.core.FssThrowable;
import fss.core.config.FssProperties;
import fss.util.FssConstants;

/**
 * This class is used to set up the Java Logger for the application to use.
 * <p>
 * All logger objects in this application will have a file handler and
 * console handler.
 * 
 * @author thinh
 *
 */
public class FssLogger {
    /**
     * The properties file.
     */
    private static final String LOGGER_PROPERTIES = "fss.core.logger.fsslogger";
    /**
     * The logger pool.
     */
    private static final Map<String, Logger> pool = new HashMap<String, Logger>();
    /**
     * The application logger.
     */
    private static Logger applicationLogger = null;    
    /**
     * The singleton.
     */
    private static FssLogger instance = null;
    /**
     * Properties file.
     */
    private FssProperties properties = null;
    /**
     * Hidden constructor.
     */
    private FssLogger() {
        properties = FssProperties.getInstance();
    }
    /**
     * Get the instance.
     * @return the instance.
     */
    public static FssLogger getInstance() {
        if(instance == null) {
            instance = new FssLogger();
        }
        return instance;
    }
    /**
     * Create a new logger.
     * <p>
     * This will write to a common 'fss.log.pos' file in the runtime directory.
     * @return a logger.
     */
    public Logger getApplicationLogger() {
        if(applicationLogger == null) {
            try {
                String home = properties.getFssApplicationLogHomeDir();
                boolean success = false;
                File file = new File(home);
                if(!file.exists()) {
                    success = file.mkdirs();
                    if(!success) {
                        throw new FssThrowable("Cannot create logger directory: " + home);
                    }
                }
                FileHandler fileHandler = new FileHandler(properties.getFssApplicationFullyQualifiedLogFile(), FssConstants.LOGGER_FILESIZE_LIMIT, 1, true);
                fileHandler.setFormatter(new FssFormatter());
                applicationLogger = Logger.getLogger("FSS", LOGGER_PROPERTIES);
                applicationLogger.addHandler(fileHandler);
                applicationLogger.setLevel(FssProperties.getInstance().getLoggerLevel());
            } catch (IOException e) {
                throw new FssThrowable(e);
            }
        }
        return applicationLogger;
    }
    /**
     * Obtain the logger for the Service Registry.
     * <p>
     * This method will prepare the appropriate log folder for the Service Registry.
     * @param name the service registry name.
     * @return the logger.
     */
    public Logger getServiceRegistryLogger(String name) {
        if(pool.containsKey(name)) {
            return pool.get(name);
        }
        Logger logger = null;
        try {
            String home = properties.getServiceRegistryHomeDir(name) + "/logs";
            boolean success = false;
            File file = new File(home);
            if(!file.exists()) {
                success = file.mkdirs();
                if(!success) {
                    throw new FssThrowable("Cannot create logger directory: " + home);
                }
            }
            FileHandler fileHandler = new FileHandler(properties.getServiceRegistryFullyQualifiedLogFile(name), FssConstants.LOGGER_FILESIZE_LIMIT, 1, true);
            fileHandler.setFormatter(new FssFormatter());
            logger = Logger.getLogger(name, LOGGER_PROPERTIES);
            logger.addHandler(fileHandler);
            logger.setLevel(FssProperties.getInstance().getLoggerLevel());
        } catch (IOException e) {
            throw new FssThrowable(e);
        }
        pool.put(name, logger);
        return logger;
    }
    /**
     * Obtain the logger for the Remote Service.
     * <p>
     * This method will prepare the appropriate log folder for the Remote Service.
     * @param name the remote service name.
     * @return the logger.
     */
    public Logger getRemoteServiceLogger(String name) {
        if(pool.containsKey(name)) {
            return pool.get(name);
        }
        Logger logger = null;
        try {
            String home = properties.getRemoteServiceHomeDir(name) + "/logs";
            boolean success = false;
            File file = new File(home);
            if(!file.exists()) {
                success = file.mkdirs();
                if(!success) {
                    throw new FssThrowable("Cannot create logger directory: " + home);
                }
            }
            FileHandler fileHandler = new FileHandler(properties.getRemoteServiceFullyQualifiedLogFile(name), FssConstants.LOGGER_FILESIZE_LIMIT, 1, true);
            fileHandler.setFormatter(new FssFormatter());
            logger = Logger.getLogger(name, LOGGER_PROPERTIES);
            logger.addHandler(fileHandler);
            logger.setLevel(FssProperties.getInstance().getLoggerLevel());
        } catch (IOException e) {
            throw new FssThrowable(e);
        }
        pool.put(name, logger);
        return logger;
    }
    /**
     * Obtain the logger for the client.
     * <p>
     * This method will prepare the appropriate log folder for the client.
     * @param name the client name.
     * @return the logger.
     */
    public Logger getClientLogger(String name) {
        if(pool.containsKey(name)) {
            return pool.get(name);
        }
        Logger logger = null;
        try {
            String home = properties.getClientHomeDir(name) + "/logs";
            boolean success = false;
            File file = new File(home);
            if(!file.exists()) {
                success = file.mkdirs();
                if(!success) {
                    throw new FssThrowable("Cannot create logger directory: " + home);
                }
            }
            FileHandler fileHandler = new FileHandler(properties.getClientFullyQualifiedLogFile(name), FssConstants.LOGGER_FILESIZE_LIMIT, 1, true);
            fileHandler.setFormatter(new FssFormatter());
            logger = Logger.getLogger(name, LOGGER_PROPERTIES);
            logger.addHandler(fileHandler);
            logger.setLevel(FssProperties.getInstance().getLoggerLevel());
        } catch (IOException e) {
            throw new FssThrowable(e);
        }
        pool.put(name, logger);
        return logger;
    }
}